<template>
    <div class="main" :id=div_id>
        <canvas :id=canvas_id ></canvas>
    </div>
</template>

<script setup>
import {ref, defineProps, onMounted, onUnmounted, getCurrentInstance} from 'vue'
import  { v4 as uuidv4 } from 'uuid'

const proxy = getCurrentInstance()
const props = defineProps({
    device:{
        type:Array,
        default:[{id:1,name:"时统设备",location:2,height:2,img:"",state:1},{id:2,name:"采集设备",location:5,height:2,img:"",state:0} ]//,
        //required: true, //是否必传
    },
    title:{
        type:String,
        default:"XXX机柜",
        required: true, //是否必传
    }
})

let defaultImg;

let canvas_id = uuidv4()
let div_id = uuidv4()
//let device =

const deviceRect = {left: 10, right: 100, top: 10, bottom: 500, width: 0, height: 0} // 设备区域
const footRect = {left: 10, right: 100, top: 10, bottom: 500, width: 0, height: 0} // 设备脚区域
let footHeight = 20
let leftPadding= 20
let rightPadding= 20
let topPadding= 30
let bottomPadding= 30

let hoverId = 1;

let slotNum = 30 //槽数量
let slotHeight = 0 //槽高度

const canvas= ref() // 画布
const painter= ref() //

let mouseBeginX=0 // 鼠标按下点
let mouseBeginY= 0 // 鼠标按下点
let mouseHoverX=0 // 鼠标悬浮坐标点X
let mouseHoverY= 0
let mouseEndX= 0 // 鼠标弹起点X
let mouseEndY= 0 // 鼠标弹起点X

//异步执行
const imageUrlToBase64 =(url) => {
    return new Promise((resolve, reject) => {//同步加载
        let image = new Image()//一定要设置为let，不然图片不显示
        image.setAttribute('crossOrigin', 'anonymous');//解决跨域问题
       // image.src = new URL(url, import.meta.url).href

        image.src =new URL('@/assets/2U_Server.jpg' ,import.meta.url).href
        image.onload = () => {//image.onload为异步加载
            let canvas = document.createElement("canvas")
            canvas.width = image.width
            canvas.height = image.height
            let context = canvas.getContext('2d')
            context.drawImage(image, 0, 0, image.width, image.height)
            let quality = 0.8
            let dataURL = canvas.toDataURL("image/jpeg", quality);//使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png，因为压缩成png后base64的字符串可能比不转换前的长！
            resolve(dataURL)
        }
        image.onerror = () => {
            reject(new Error('图像加载失败'))
        }
    })
}

// 检测浏览器
const detectBrowser =() => {
    if (!window.FileReader) {
        console.log('你的浏览器不支持读取文件')
    }
}
const drawFoot = () =>{
    painter.value.save()
    painter.value.strokeStyle = '#03061d'
    painter.value.fillStyle = painter.value
    painter.value.lineWidth = 1
    painter.value.beginPath()

    painter.value.moveTo(footRect.left + 5, footRect.top)
    painter.value.lineTo(footRect.left + 5 + 30, footRect.top)
    painter.value.lineTo(footRect.left + 5 + 25, footRect.bottom)
    painter.value.lineTo(footRect.left + 5 + 5, footRect.bottom)
    painter.value.lineTo(footRect.left + 5, footRect.top)

    painter.value.moveTo(footRect.right - 5, footRect.top)
    painter.value.lineTo(footRect.right - 5 - 30, footRect.top)
    painter.value.lineTo(footRect.right - 5 - 25, footRect.bottom)
    painter.value.lineTo(footRect.right - 5 - 5, footRect.bottom)
    painter.value.lineTo(footRect.right - 5, footRect.top)

    painter.value.fillStyle = '#404040'
    painter.value.fill()
    painter.value.stroke()
    painter.value.closePath()
    painter.value.restore()
}

const drawFrame = () =>{
    painter.value.save()

    painter.value.fillStyle = '#342E33'
    painter.value.fillRect(deviceRect.left, deviceRect.top, deviceRect.width, deviceRect.height)

    painter.value.fillStyle = '#4A4A4A'
    painter.value.fillRect(0, 0, leftPadding, canvas.value.height-footHeight)
    painter.value.fillRect(deviceRect.right, 0, rightPadding, canvas.value.height-footHeight)

    painter.value.fillStyle = '#404040'
    painter.value.fillRect(0, 0, canvas.value.width, topPadding)
    painter.value.fillRect(0, deviceRect.bottom, canvas.value.width, bottomPadding)

    painter.value.fillRect(leftPadding, 0, deviceRect.width, topPadding)
    painter.value.fillRect(leftPadding, deviceRect.bottom, deviceRect.width, bottomPadding)

    painter.value.beginPath()
    painter.value.strokeStyle = '#e5e0e0'
    painter.value.lineWidth = 3
    //顶部左
    painter.value.moveTo(deviceRect.left, 0)
    painter.value.lineTo(deviceRect.left, topPadding)
    //顶部右
    painter.value.moveTo(deviceRect.right, 0)
    painter.value.lineTo(deviceRect.right, topPadding)

    //底部左
    painter.value.moveTo(deviceRect.left, deviceRect.bottom)
    painter.value.lineTo(deviceRect.left, deviceRect.bottom + topPadding)
    //底部右
    painter.value.moveTo(deviceRect.right, deviceRect.bottom)
    painter.value.lineTo(deviceRect.right, deviceRect.bottom + topPadding)



    painter.value.closePath()
    painter.value.stroke()
    painter.value.restore()


    painter.value.save()
    painter.value.beginPath()
    painter.value.strokeStyle = '#e5e0e0'
    painter.value.lineWidth = 1
    //顶部上
    painter.value.moveTo(deviceRect.left, topPadding-1)
    painter.value.lineTo(deviceRect.right, topPadding-1)
    //顶部下
    painter.value.moveTo(deviceRect.left, 0)
    painter.value.lineTo(deviceRect.right, 0)

    //底部上
    painter.value.moveTo(deviceRect.left, deviceRect.bottom)
    painter.value.lineTo(deviceRect.right, deviceRect.bottom)
    //底部下
    painter.value.moveTo(deviceRect.left, deviceRect.bottom + topPadding)
    painter.value.lineTo(deviceRect.right, deviceRect.bottom + topPadding)

    //绘制机柜标题
    painter.value.fillStyle = '#ffffff'
    painter.value.font = "20px Verdana"
    let txtHeight = painter.value.measureText(props.title).actualBoundingBoxAscent + painter.value.measureText(props.title).actualBoundingBoxDescent;
    painter.value.fillText(props.title, (canvas.value.width - painter.value.measureText(props.title).width)/2, (topPadding + txtHeight)/2, painter.value.measureText(props.title).width)

    painter.value.stroke()
    painter.value.closePath()
    painter.value.restore()


}


const drawSlot = () =>{
    painter.value.save()
    painter.value.strokeStyle = '#03061d'
    painter.value.lineWidth = 1
    painter.value.beginPath()

    painter.value.fillStyle = '#6b6a6a'
    painter.value.font = '15px Verdana'

    for (let i=1;i <= slotNum;i++){
        painter.value.moveTo(deviceRect.left, deviceRect.top + slotHeight * i)
        painter.value.lineTo(deviceRect.right, deviceRect.top + slotHeight * i)
        let txtHeight = painter.value.measureText((slotNum - i + 1).toString()).actualBoundingBoxAscent + painter.value.measureText((slotNum - i + 1).toString()).actualBoundingBoxDescent;
        painter.value.fillText((slotNum - i + 1).toString(), (canvas.value.width - painter.value.measureText((slotNum - i + 1).toString()).width)/2, deviceRect.top + slotHeight * i - (slotHeight - txtHeight)/2, painter.value.measureText((slotNum - i + 1).toString()).width)
    }
    painter.value.stroke()
    painter.value.closePath()
    painter.value.restore()
}

const drawDevice = () =>{

    painter.value.save()
    let img = new Image();

    for(let i=0;i< props.device.length;i++){
        if(props.device.at(i).img  === undefined || props.device.at(i).img === null || props.device.at(i).img === ''){
            //img.src =new URL('@/assets/2U_Server.jpg' ,import.meta.url).href;
            img.src = defaultImg
        }else{
            img.src = props.device.at(i).img;
            // img.src =new URL(props.device.at(i).img,import.meta.url).href;
        }

        if(hoverId === props.device.at(i).id){
            painter.value.drawImage(img,deviceRect.left-10, deviceRect.bottom - ((props.device.at(i).location - 1 + props.device.at(i).height) * slotHeight)-10, deviceRect.width+20, props.device.at(i).height * slotHeight+20)
            painter.value.font = '17px Verdana'
        }else{
            painter.value.font = '15px Verdana'
            painter.value.drawImage(img,deviceRect.left, deviceRect.bottom - ((props.device.at(i).location - 1 + props.device.at(i).height) * slotHeight), deviceRect.width, props.device.at(i).height * slotHeight)
        }

        painter.value.fillStyle = '#e8e850'
        let txtHeight = painter.value.measureText(props.device.at(i).name).actualBoundingBoxAscent + painter.value.measureText(props.device.at(i).name).actualBoundingBoxDescent;
        painter.value.fillText(props.device.at(i).name, deviceRect.right - painter.value.measureText(props.device.at(i).name).width,deviceRect.bottom - ((props.device.at(i).location - 1) * slotHeight)-5, painter.value.measureText(props.device.at(i).name).width)

        painter.value.beginPath()
        if(props.device.at(i).state === 0){
            painter.value.fillStyle = "#C0C0C0"
        }else if(props.device.at(i).state === 1){
            painter.value.fillStyle = "#17CC6D"
        }
        painter.value.arc(deviceRect.right - 10,deviceRect.bottom - ((props.device.at(i).location - 1 + props.device.at(i).height) * slotHeight)+10,10,0,2 * Math.PI);
        painter.value.fill();
        painter.value.stroke();
        painter.value.closePath();
    }
    painter.value.restore()

}

const measureText = function (fontSize, fontFamily, text) {
    let spanDom = document.createElement('span')
    spanDom.style.margin = '0'
    spanDom.style.fontSize = fontSize
    spanDom.style.opacity = '0'
    // spanDom.style.fontFamily = fontFamily;
    spanDom.innerHTML = text
    document.body.append(spanDom)
    let sizeD = {}
    sizeD.width = spanDom.offsetWidth
    sizeD.height = spanDom.offsetHeight / 2
    spanDom.remove()
    return sizeD
}

const paint= () => {
    painter.value.clearRect(0, 0,  canvas.value.width,  canvas.value.height)
    drawFoot()
    drawFrame()
    drawSlot()
    drawDevice()
}
const resetRect = () => {
    canvas.value.width = document.getElementById(div_id).clientWidth
    canvas.value.height = document.getElementById(div_id).clientHeight
    //设备脚区域
    footRect.left = 0
    footRect.right = canvas.value.width
    footRect.top = canvas.value.height - footHeight
    footRect.bottom = canvas.value.height
    footRect.width = canvas.value.width
    footRect.height = footHeight
    //设备区域
    deviceRect.left = leftPadding
    deviceRect.right = canvas.value.width - rightPadding
    deviceRect.top = topPadding
    deviceRect.bottom = canvas.value.height - footHeight - bottomPadding
    deviceRect.width = deviceRect.right - deviceRect.left
    deviceRect.height = deviceRect.bottom - deviceRect.top

    slotHeight = deviceRect.height / slotNum;
    paint()
}
const scroll= function () {
    if (window.pageYOffset != null) { // ie9+ 高版本浏览器
        // 因为 window.pageYOffset 默认的是  0  所以这里需要判断
        return {
            left: window.pageXOffset,
            top: window.pageYOffset
        }
    } else if (document.compatMode === 'CSS1Compat') { // 标准浏览器   来判断有没有声明DTD
        return {
            left: document.documentElement.scrollLeft,
            top: document.documentElement.scrollTop
        }
    }
    return { // 未声明 DTD
        left: document.body.scrollLeft,
        top: document.body.scrollTop
    }

}
const canvasDown= function (e) {

    mouseBeginX = e.pageX -  canvas.value.offsetLeft
    mouseBeginY = e.pageY -  canvas.value.offsetTop
    mouseEndX =  mouseBeginX
    mouseEndY =  mouseBeginY

    if(hoverId !== 0){
        proxy.emit("deviceOnClick",hoverId)
    }
}
const canvasMove= function (e) {
    mouseHoverX = e.pageX -  canvas.value.offsetLeft
    mouseHoverY = e.pageY -  canvas.value.offsetTop
    mouseEndX =  mouseHoverX
    mouseEndY =  mouseHoverY

    hoverId = 0;

    for(let i=0;i<props.device.length;i++){
        let nowDeviceLetf = deviceRect.left;
        let nowDeviceRight = deviceRect.right;
        let nowDeviceTop = deviceRect.bottom - (props.device.at(i).location - 1 + props.device.at(i).height) * slotHeight;
        let nowDeviceBottom = deviceRect.bottom - (props.device.at(i).location - 1) * slotHeight;

        if( mouseHoverX > nowDeviceLetf && mouseHoverX < nowDeviceRight && mouseHoverY > nowDeviceTop && mouseHoverY < nowDeviceBottom){
            hoverId = props.device.at(i).id;
            break;
        }
    }
    paint()
}
const canvasUp = function (e) {
    mouseEndX = e.pageX -  canvas.value.offsetLeft
    mouseEndY = e.pageY -  canvas.value.offsetTop
    paint()
}
const canvasDblClick= function (e) {

}
const canvasWheel= function (e) {

}
const canvasOver= function (e) {

}
const canvasOut= function (e) {
    // if ( chooseIng) {
    //     mouseEndX = e.clientX -  canvas.value.offsetLeft
    //     mouseEndY = e.clientY -  canvas.value.offsetTop
    //     chooseIng = false
    // }
    // selectFreq = false
    // moveFreq = false
    // selectLevel = false
    // moveLevel = false
    // subXLineShow = false;
    // subYLineShow = false;
}
const initData = () => {
    canvas.value = document.getElementById(canvas_id)
    canvas.value.width = 1300
    canvas.value.height = 700
    painter.value = canvas.value.getContext('2d')
    painter.value.fillStyle = 'rgb(133,155,238)'

    // document.getElementById('maa').addEventListener('resize',  resetRect)
    window.addEventListener('resize', resetRect)
    canvas.value.addEventListener('contextmenu', function (e) {
        e.preventDefault()
        // e.stopPropagation()
        // return false
    })
    canvas.value.addEventListener('mousedown', canvasDown)
    canvas.value.addEventListener('mousemove', canvasMove)
    canvas.value.addEventListener('mouseup', canvasUp)
    canvas.value.addEventListener('dblclick', canvasDblClick)
    canvas.value.addEventListener('mousewheel', canvasWheel)
    canvas.value.addEventListener('mouseover', canvasOver)
    canvas.value.addEventListener('mouseout',  canvasOut)

    detectBrowser()
    resetRect()
    paint()
}

onMounted(() => {
    imageUrlToBase64("'@/assets/2U_Server.png'").then(res  =>{
        defaultImg = res
    })
    initData()
})
onUnmounted(() => {
})
</script>

<style>
.main {
    margin-right: 5px;
    width: 280px;
    height: 800px;
}

</style>